/**
 * Created by ${PRODUCT_NAME}.
 * User: skylerparr
 * Date: 12/19/10
 * Time: 8:47 PM
 * To change this template use File | Settings | File Templates.
 */
package com.thoughtorigin.service {
import com.thoughtorigin.asset.AssetManager;
import com.thoughtorigin.events.ModuleLoaderEvent;
import com.thoughtorigin.loader.AbstractLoader;
import com.thoughtorigin.loader.LoaderItem;
import com.thoughtorigin.meta.MetaOperator;
import com.thoughtorigin.module.Module;
import com.thoughtorigin.module.ModuleLoader;
import com.thoughtorigin.service.AbstractService;
import com.thoughtorigin.service.Message;

import flash.display.DisplayObject;
import flash.system.ApplicationDomain;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.system.SecurityDomain;

public class ModuleLoaderService extends AbstractService {
    public static const SERVICE_NAME: String = "ModuleLoaderService";

    private var _assetManager: AssetManager;
    private var _moduleLoader: ModuleLoader;

    private static var _previousModule: Module;
    private var _metaOperator:MetaOperator;

    public function ModuleLoaderService() {
    }

    override public function handoff(message:Message):void {
        if(_previousModule) {
            _moduleLoader.unloadModule(_previousModule);
        }
        var sectionName: String = deeplinkMessage.section;
        sectionName = sectionName.charAt(0).toUpperCase() + sectionName.substring(1);
        _assetManager.loadAsset(getLoader(deeplinkMessage.section + ".swf"), moduleLoaded, moduleFail);
    }

    private function moduleLoaded(disp: DisplayObject): void {
        _moduleLoader.loadModule(Module(disp));
        _previousModule = Module(disp);
        _metaOperator.injectObject(disp, moduleInjected)
    }

    private function moduleInjected(disp: DisplayObject):void {
        dispatchEvent(new ModuleLoaderEvent(ModuleLoaderEvent.LOAD_MODULE, disp));
    }

    private function moduleFail(obj: Object): void {
        throw new Error("Module failed to load");
    }

    override public function get serviceName():String {
        return SERVICE_NAME;
    }

    [Inject]
    public function set assetManager(value: AssetManager): void {
        _assetManager = value;
    }

    [Inject]
    public function set moduleLoader(value: ModuleLoader): void {
        _moduleLoader = value;
    }

    [Inject]
    public function set metaOperator(value: MetaOperator): void {
        _metaOperator = value;
    }

    protected function getLoader(url: String): AbstractLoader {
        var retVal: LoaderItem = new LoaderItem(url);
        var loaderContext: LoaderContext = new LoaderContext(true);
        loaderContext.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
        retVal.loaderContext = loaderContext;
        return retVal;
    }

    override public function get createNew():Boolean {
        return true;
    }
}
}
